package main.java.com.imooc.fanshe.Class类的使用;

import javax.crypto.spec.PSource;

/**
 * 表示Class类的实例
 */
public class ClassDemo1 {
    public static void main(String[] args) {
        // Foo的实例对象如何表示
        Foo foo1 = new Foo();// foo1就表示出来了，foo1代表Foo的实例对象

        // Foo这个类也是一个实例对象，Class类的实例对象，如何表示呢？有三种表示方式
        // 任何一个类都是Class类的实例对象，这个实例对象有三种表示方式

        // 1 类名.class --> 实际在告诉我们任何一个类都有一个隐含的静态成员变量class
        Class c1 = Foo.class;// c1，c2表示Class的实例对象

        // 2 已知该类的对象通过getClass()方法
        Class c2 = foo1.getClass();// c1，c2表示Class的实例对象

        /* 官网说： c1，c2表示了Foo类的类类型（class type），意思就是Foo这个类本身就是Class类的实例对象
         * 万事万物皆对象
         * 类也是对象，是Class类的对象
         * 这个对象称为该类的类类型
         */

        // 不管c1还是c2，都代表了Foo的类类型，一个类只可能是Class类的一个实例对象
        System.out.println(c1 == c2);

        // 3 Class.forName
        Class c3 = null;
        try {
            c3 = Class.forName("main.java.com.imooc.fanshe.Class类的使用.Foo");

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        System.out.println(c2 == c3);

        // 我们完全可以通过类的类类型创建该类的对象实例 --> 通过c1 or c2 or c3 创建Foo的实例
        // c1是Foo类的类类型，所以 c1.newInstance();创建出来的对象是Foo类的对象，所以需要做强制类型转换
        try {
            Foo foo = (Foo) c1.newInstance();
            // 需要有无参数的构造方法，才可以调用
            foo.print();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }
}

// class的父类，这个类是对象
class Foo {
    void print() {
        System.out.println("foo");
    }
}